#include "Digestor.h"
#include <stdio.h>
#include <string.h>
#include "pcre.h"
#define OVECCOUNT 30


PEPTIDERECORD* argc_digest (PROTEINRECORD* library, int missed_cleavages , int size_of_library){
	// define things for regex compile //
	pcre *re;
	const char *error;
	int erroroffset;
	int ovector[OVECCOUNT];
	char *regex = "R";
	// compile regex //
	re = pcre_compile(regex,0,&error,&erroroffset,NULL);
	// loop through library //
	int i;
	PEPTIDERECORD *digested_library = NULL;
	int elements_allocated = 0;
	int current_element = 0;
	for (i = 0 ; i < size_of_library; i++){
		// declaring shit //
		int cleavage_sites_allocated = 1000;
		int* cleavage_site_array = realloc(NULL, cleavage_sites_allocated*sizeof(int));
		int cleavage_site_counter = 1;
		// we want to make sure we always start at the begining of the string so we'll set index 0 and start at index 1;
		cleavage_site_array[0]=0;
		int rc = 0;
		int search_offset = 0;
		// while i don't have the answer to the universe //
		while(rc != 42){
			rc = pcre_exec(re,0,library[i].sequence,strlen(library[i].sequence),search_offset,0,ovector,OVECCOUNT);
			if (rc == -1){
				rc = 42; // if i reach the end of the string rc returns -1 - ie the answer of the universe
				}
			else{
				cleavage_site_array[cleavage_site_counter] = (ovector[0]+1); // asign the cut site - + 1 because the R stays to the left
				search_offset = ovector[1]; // shift the begining of the search 
				cleavage_site_counter++; // increment to the next index
				}
			}
	// make sure we add the last nucleotide to the array //
	cleavage_site_array[cleavage_site_counter] = strlen(library[i].sequence) ;
	// substring out all possible peptides from a protein record //
	int j;// Counter to track cleavage site array index
	int h; // counter to track missed cleavage number
	int fragment_counter = 1; // counter to track how many fragments each peptide creates;
	for( h = 0; h <= missed_cleavages; h++){
		for(j = 0 ; (j <= cleavage_site_counter) && ((j+(1+h)) <= cleavage_site_counter) ; j++){
			PEPTIDERECORD temp; // temporary PEPTIDERECORD;
			// assign stuff i know that doesn't need allocation //
			temp.fragment_start = cleavage_site_array[j];
			temp.fragment_end = cleavage_site_array[(j+(1+h))];
			temp.parent_name = library[i].name;
			if(temp.fragment_start == 0 && temp.fragment_end == strlen(library[i].sequence)){
				temp.fragment_number = 0;
				temp.fragment_sequence = library[i].sequence;
				temp.fragment_mass = mass_of_peptide(library[i].sequence);
				}
			else{
				temp.fragment_number = fragment_counter;
				temp.fragment_sequence = malloc((temp.fragment_end - temp.fragment_start) + 1 * sizeof(char));
				temp.fragment_sequence = strndup(library[i].sequence+temp.fragment_start,(temp.fragment_end - temp.fragment_start));
				temp.fragment_mass = mass_of_peptide(temp.fragment_sequence);
				}
			if(elements_allocated == current_element){
				if(elements_allocated == 0){
					elements_allocated = 110;
					}
				else{
					elements_allocated += 5;
					}
				void *_tmp = realloc(digested_library, (elements_allocated * sizeof(PEPTIDERECORD)));
				if (!_tmp){ 
					fprintf(stderr, "ERROR: Couldn't realloc memory!\n");
					break; 
					}
				digested_library = (PEPTIDERECORD*)_tmp;
				}
				if((temp.fragment_end - temp.fragment_start) > 1 ){
					digested_library[current_element] = temp;
					current_element++;
					fragment_counter++;
					}
			}
		}
	//free all the memory //
	free(cleavage_site_array);
	}
	int k = 0;
	for( k = 0; k < current_element; k++){
	printf("Fragemnt number : %d\n", digested_library[k].fragment_number);
	printf("Frag start : %d Frag end : %d\n", digested_library[k].fragment_start , digested_library[k].fragment_end);
	printf("Fragment parent name : %s\n" , digested_library[k].parent_name);
	printf("Fragment sequence : %s\n",digested_library[k].fragment_sequence);
	printf("Fragment mass : %f\n\n", digested_library[k].fragment_mass);	
		}
	//stuff//
	return digested_library;
}



float mass_of_peptide(char *peptide){
	float mass = 0;
	int i;
	printf("entered mass loop\n");
	char* AA = peptide;
	while( *AA != '\0'){
		if ( *AA =='A') {
			mass += 71.0788;
			}
		if ( *AA== 'R') {
			mass += 156.1875;
			}
		if ( *AA== 'N') {
			mass += 114.1038;
			}
		if ( *AA== 'D') {
			mass += 115.0886;
			}
		if ( *AA== 'C') {
			mass += 103.1388;
			}
		if ( *AA== 'E') {
			mass += 129.1155;
			}
		if ( *AA== 'Q') {
			mass += 128.1307;
			}
		if ( *AA== 'G') {
			mass += 57.0519;
			}
		if ( *AA== 'H') {
			mass += 137.1411;
			}
		if ( *AA== 'I') {
			mass += 113.1594;
			}
		if ( *AA== 'L') {
			mass += 113.1594;
			}
		if ( *AA== 'K') {
			mass += 128.1741;
			}
		if ( *AA== 'M') {
			mass += 131.1926;
			}
		if ( *AA== 'F') {
			mass += 147.1766;
			}
		if ( *AA== 'P') {
			mass += 97.1167;
			}
		if ( *AA== 'S') {
			mass += 87.0782;
			}
		if ( *AA== 'T') {
			mass += 101.1051;
			}
		if ( *AA== 'W') {
			mass += 186.2132;
			}
		if ( *AA== 'Y') {
			mass += 163.1760;
			}
		if ( *AA== 'V') {
			mass += 99.1362;
			}
		AA++;
	}
	return mass;
}
